﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Devices.Sensors;
using Microsoft.Devices;
using System.Diagnostics;
using System.Threading;
using System.Windows.Threading;
using System.Net.NetworkInformation;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using Curling.CurlingServer;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Xml;
using System.Text;

namespace Curling
{
    public partial class MainPage : PhoneApplicationPage
    {
        readonly IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

        CurlingServiceClient CurlingService;
        PlayerProfile Opponent;
       
        Accelerometer accelerometer;
        
        GameManager gameManager;
        AnimationManager CameraAnimation;
        AIManager aiManager;

        DispatcherTimer Timer;

        DispatcherTimer DownloadAndUploadDataTimer;

        Score score;

        Random rand = new Random();

        bool IsShowHand = false;
        bool SupressHand = false;
        bool SupressSystemTray = false;
        bool FirstHoglineFall = false;

        bool IsPause = false;

        long LastTickCount;
        long LastAccelerometerReading;

        bool IsPlayOverInternet;

        int RoundResult;

        double VerticalScroll;

        public MainPage()
        {
            InitializeComponent();
        }

        void systemTray_ReplayEvent(object sender, EventArgs e)
        {
            if (!gameManager.replay.IsPlaying)
            {
                gameManager.CurrentGameTime = TimeSpan.FromMilliseconds(0);

                if (IsShowHand)
                {
                    HideHand.Begin();
                    HideMap.Begin();
                    IsShowHand = false;
                }

                VisualStateManager.GoToState(this, "ReplayVisible", true);
                systemTray.IsReplayEnabled = false;
                systemTray.IsNewGameEnabled = false;

                scrollViewer.ScrollToVerticalOffset(scrollViewer.ScrollableHeight);

                gameManager.replay.ReplayFinished += new ReplayManager.ReplayFinishedEventHandler(replay_ReplayFinished);
                
                gameManager.replay.StartPlay();
            }
        }

        void replay_ReplayFinished(object sender, EventArgs e)
        {
            gameManager.replay.ReplayFinished -= new ReplayManager.ReplayFinishedEventHandler(replay_ReplayFinished);
            gameManager.ReplayFinished();

            VisualStateManager.GoToState(this, "ReplayCollapsed", true);
            systemTray.IsReplayEnabled = true;

            SoundManager.PlayBroomSound(0.0);

            if (gameManager.gameState == GameState.GameEnded)
            {
                systemTray.IsNewGameEnabled = true;
            }

            if (BroomManager.IsShowBroom)
            {
                HideBroom.Begin();
                BroomManager.IsShowBroom = false;
            }

            SupressHand = false;

            if (gameManager.gameState == GameState.StoneOnStart)
            {
                if (systemTray.IsAutoScroll)
                {
                    CameraAnimation.Duration = 0.5;
                    CameraAnimation.From = scrollViewer.VerticalOffset;
                    CameraAnimation.To = scrollViewer.ScrollableHeight;

                    CameraAnimation.Start();
                }
            }
            else
            {
                CameraAnimation.Duration = 0.6;
                CameraAnimation.From = scrollViewer.VerticalOffset;
                CameraAnimation.To = GameManager.Hackline;

                CameraAnimation.Start();
            }

            if (gameManager.gameState == GameState.StoneOnStart)
            {
                gameManager.CurrentStone--;
                gameManager.StoneToStart();
            }
        }

        void systemTray_NewGameEvent(object sender, EventArgs e)
        {
            NewGame(true);
        }

        private void NewGame(bool NotifyOpponent)
        {
            if (score.CurrentRound == 10)
            {
                score.Reset();
            }

            //gameManager.ChooseStartPlayer(RoundResult);
            gameManager.NewRound();

            MakeScreenshot();

            if (gameManager.ActivePlayer == PlayerColor.Yellow && gameManager.Player1Type == PlayerType.Internet)
            {
                OpponentShotText.Visibility = System.Windows.Visibility.Visible;
            }

            if (gameManager.ActivePlayer == PlayerColor.Red && gameManager.Player2Type == PlayerType.Internet)
            {
                OpponentShotText.Visibility = System.Windows.Visibility.Visible;
            }
            //systemTray.ChangePlayer(gameManager.ActivePlayer);            

            CameraAnimation.Duration = 1.0;
            CameraAnimation.From = scrollViewer.VerticalOffset;
            CameraAnimation.To = scrollViewer.ScrollableHeight;

            CameraAnimation.Start();

            systemTray.IsReplayEnabled = false;

            if (IsPlayOverInternet && NotifyOpponent)
            {
                if (gameManager.CurrentStone > 1)
                {
                    gameManager.gameData = new GameData();

                    foreach (Stone stone in gameManager.Stones)
                    {
                        gameManager.gameData.AddStoneFrame(stone.stoneEntity);
                    }

                    string GameDataXml = gameManager.gameData.ToXml();

                    CurlingService.UploadDataAsync(App.AuthToken, Opponent.ID, GameDataXml);
                }
            }
        }

        void systemTray_ScrollEvent(object sender, EventArgs e)
        {
            if (scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight || gameManager.gameState != GameState.StoneOnStart || (gameManager.replay != null && gameManager.replay.IsPlaying))
            {
                systemTray.IsAutoScroll = !systemTray.IsAutoScroll;
            }
            else
            {
                CameraAnimation.From = scrollViewer.VerticalOffset;
                CameraAnimation.To = scrollViewer.ScrollableHeight;

                CameraAnimation.Start();
            }
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (PhoneApplicationService.Current.State.ContainsKey("GoToMenu"))
            {
                PhoneApplicationService.Current.State.Remove("GoToMenu");
                NavigationService.GoBack();
                return;
            }
            
            LastTickCount = DateTime.Now.Ticks;

            if (gameManager == null)
            {
                ShowHand.Completed += new EventHandler(ShowHand_Completed);
                HideHand.Completed += new EventHandler(HideHand_Completed);

                bool Resume = true;

                if (PhoneApplicationService.Current.State.ContainsKey("resume"))
                {
                    if ((bool)PhoneApplicationService.Current.State["resume"] == false)
                    {
                        settings.Remove("IsPause");
                        settings.Remove("VerticalScroll");
                        GameManager.Delete();
                        PhoneApplicationService.Current.State.Remove("GameManager");
                        settings.Remove("GameManager");

                        Resume = false;
                        //settings.Remove("gameManager");

                        if (settings.Contains("Score"))
                        {
                            Score score = (Score)settings["Score"];

                            if (score != null && score.CurrentRound != 10)
                                score.SaveGameResult(true);

                            settings.Remove("Score");
                        }
                    }

                    PhoneApplicationService.Current.State.Remove("resume");
                }

                if (settings.Contains("GameManager") && Resume)//PhoneApplicationService.Current.State.ContainsKey("GameManager") && PhoneApplicationService.Current.State["GameManager"] != null && Resume)
                //if (GameManager.IsExists())
                //if (settings.Contains("gameManager"))
                {
                    gameManager = (GameManager)settings["GameManager"];//PhoneApplicationService.Current.State["GameManager"];// GameManager.Load();// settings["gameManager"];
                    gameManager.StoneAdded += new GameManager.StoneAddedEventHandler(gameManager_StoneAdded);

                    gameManager.Stones = new List<Stone>();

                    gameManager.GenerateStones(GameManager.StonesCount, false);

                    for (int i = 0; i < GameManager.StonesCount; i++)
                    {
                        gameManager.Stones[i].stoneEntity = StoneEntity.Load(i);
                        gameManager.Stones[i].stoneEntity.stone = gameManager.Stones[i];
                        gameManager.Stones[i].ChangeColor(gameManager.Stones[i].stoneEntity.stoneColor);
                        gameManager.Stones[i].stoneEntity.soundManager.LoadSounds();
                    }

                    if (gameManager.CurrentStone < GameManager.StonesCount)
                    {
                        gameManager.DeliveryStone = gameManager.Stones[gameManager.CurrentStone - 1];
                    }
                    else
                    {
                        gameManager.DeliveryStone = gameManager.Stones[GameManager.StonesCount - 1];
                    }

                    if ((gameManager.gameState == GameState.StoneOnStart || gameManager.gameState == GameState.GameEnded) && gameManager.CurrentStone > 1 && gameManager.IsPersonActive)
                    {
                        systemTray.IsReplayEnabled = true;
                    }

                    if (gameManager.gameState == GameState.GameEnded)
                    {
                        systemTray.IsNewGameEnabled = true;
                    }

                    if (settings.Contains("AIManager"))
                    {
                        aiManager = (AIManager)settings["AIManager"];
                        if (aiManager != null)
                            aiManager.gameManager = gameManager;
                    }

                    systemTray.ChangePlayer(gameManager.ActivePlayer);
                }
                else
                {
                    gameManager = new GameManager();
                    gameManager.StoneAdded += new GameManager.StoneAddedEventHandler(gameManager_StoneAdded);

                    if (PhoneApplicationService.Current.State.ContainsKey("Player1Type") && PhoneApplicationService.Current.State.ContainsKey("Player2Type"))
                    {
                        gameManager.Player1Type = (PlayerType)PhoneApplicationService.Current.State["Player1Type"];
                        gameManager.Player2Type = (PlayerType)PhoneApplicationService.Current.State["Player2Type"];

                        if (gameManager.Player1Type == PlayerType.Computer || gameManager.Player2Type == PlayerType.Computer)
                        {
                            aiManager = new AIManager(gameManager);
                        }

                        ReplayManager.IsEnabled = true;

                        if (gameManager.Player1Type == PlayerType.Internet || gameManager.Player2Type == PlayerType.Internet)
                        {                            
                            CurlingService = (CurlingServiceClient)PhoneApplicationService.Current.State["CurlingService"];
                            CurlingService.UploadDataCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(CurlingService_UploadDataCompleted);
                            CurlingService.DownloadDataCompleted += new EventHandler<DownloadDataCompletedEventArgs>(CurlingService_DownloadDataCompleted);

                            IsPlayOverInternet = true;

                            DownloadAndUploadDataTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1.5) };
                            DownloadAndUploadDataTimer.Tick += new EventHandler(DownloadAndUploadDataTimer_Tick);
                            
                            ReplayManager.IsEnabled = false;

                            //if (gameManager.IsInternetActive)
                            //{
                                DownloadAndUploadDataTimer.Start();
                            //}

                            if (gameManager.Player1Type == PlayerType.Internet)
                            {
                                OpponentShotText.Visibility = System.Windows.Visibility.Visible;
                            }

                            Opponent = (PlayerProfile)PhoneApplicationService.Current.State["Opponent"];
                        }

                        //Rink1Image.Source = new BitmapImage(new Uri("Images/Rink/Skin1/rink1.jpg", UriKind.Relative));
                        //Rink2Image.Source = new BitmapImage(new Uri("Images/Rink/Skin1/rink2.jpg", UriKind.Relative));
                        //Rink3Image.Source = new BitmapImage(new Uri("Images/Rink/Skin1/rink3.jpg", UriKind.Relative));
                    }
                    else
                    {
                        gameManager.Player1Type = PlayerType.Person;
                        gameManager.Player2Type = PlayerType.Person;
                    }

                    gameManager.ChooseStartPlayer(0);
                    gameManager.NewRound();
                    systemTray.ChangePlayer(gameManager.ActivePlayer);
                }

                if (settings.Contains("IsPause") && (gameManager.gameState != GameState.StoneOnStart || gameManager.IsComputerActive))
                {
                    IsPause = (bool)settings["IsPause"];

                    if (IsPause)
                    {
                        VisualStateManager.GoToState(this, "PauseOn", true);
                    }
                }

                if (settings.Contains("Score"))
                {
                    score = (Score)settings["Score"];
                }
                else
                {
                    string Player1 = "Player 1";
                    string Player2 = "Player 2";

                    if (PhoneApplicationService.Current.State.ContainsKey("Player1Name"))
                    {
                        Player1 = (string)PhoneApplicationService.Current.State["Player1Name"];
                    }

                    if (PhoneApplicationService.Current.State.ContainsKey("Player2Name"))
                    {
                        Player2 = (string)PhoneApplicationService.Current.State["Player2Name"];
                    }

                    score = new Score(new Player() { Name = Player1, color = PlayerColor.Yellow }, new Player() { Name = Player2, color = PlayerColor.Red });
                }
                ScoreTable1.DataContext = score;
                ScoreTable2.DataContext = score;

                systemTray.Score = score;
                systemTray.ScrollEvent += new SystemTray.ScrollEventHandler(systemTray_ScrollEvent);
                systemTray.NewGameEvent += new SystemTray.NewGameEventHandler(systemTray_NewGameEvent);
                systemTray.ReplayEvent += new SystemTray.ReplayEventHandler(systemTray_ReplayEvent);

                if (gameManager.Player1Type == PlayerType.Computer)
                {
                    systemTray.Player1Active.Source = new BitmapImage(new Uri("Images/SystemTray/ComputerActive.png", UriKind.Relative));
                    systemTray.Player1Passive.Source = new BitmapImage(new Uri("Images/SystemTray/ComputerPassive.png", UriKind.Relative));
                }
                else if (gameManager.Player1Type == PlayerType.Internet)
                {
                    systemTray.Player1Active.Source = new BitmapImage(new Uri("Images/SystemTray/InternetActive.png", UriKind.Relative));
                    systemTray.Player1Passive.Source = new BitmapImage(new Uri("Images/SystemTray/InternetPassive.png", UriKind.Relative));
                }

                if (gameManager.Player2Type == PlayerType.Computer)
                {
                    systemTray.Player2Active.Source = new BitmapImage(new Uri("Images/SystemTray/ComputerActive.png", UriKind.Relative));
                    systemTray.Player2Passive.Source = new BitmapImage(new Uri("Images/SystemTray/ComputerPassive.png", UriKind.Relative));
                }
                else if (gameManager.Player2Type == PlayerType.Internet)
                {
                    systemTray.Player2Active.Source = new BitmapImage(new Uri("Images/SystemTray/InternetActive.png", UriKind.Relative));
                    systemTray.Player2Passive.Source = new BitmapImage(new Uri("Images/SystemTray/InternetPassive.png", UriKind.Relative));
                }

                if (settings.Contains("ScrollMode"))
                {
                    systemTray.IsAutoScroll = (bool)settings["ScrollMode"];
                }

                if (settings.Contains("Sound"))
                {
                    systemTray.IsSoundOn = (bool)settings["Sound"];
                    SoundManager.Mute = !systemTray.IsSoundOn;
                }
            }
            
            gameManager.DeliveredStonePostitonChanged += new GameManager.StonePostitonChangedEventHandler(gameManager_DeliveredStonePostitonChanged);
            gameManager.ActivePlayerChanged += new GameManager.ActivePlayerChangedEventHandler(gameManager_ActivePlayerChanged);
            gameManager.FallEvent += new GameManager.FallEventHandler(gameManager_Fall);
            gameManager.GameEnded += new GameManager.GameEndedEventHandler(gameManager_GameEnded);

            if (!IsPlayOverInternet)
            {
                settings["GameManager"] = gameManager;
            }
        }

        void gameManager_Fall(object sender, Fall e)
        {
            if (e.type == FallType.FirstHogline)
            {
                //if (IsShowHand)
                //{
                //Debug.WriteLine("fall");
                    gameManager.LeaveStone();

                    LeaveStone.Begin();

                    FirstHoglineFall = true;

                    IsShowHand = false;
                //}
            }
        }

        void gameManager_GameEnded(object sender, EventArgs e)
        {
            RoundResult = gameManager.GetRoundResult();

            if (gameManager.ActivePlayer == PlayerColor.Yellow)
            {
                gameManager.ActivePlayer = PlayerColor.Red;
                gameManager.StartPlayer = PlayerColor.Red;
            }
            else
            {
                gameManager.ActivePlayer = PlayerColor.Yellow;
                gameManager.StartPlayer = PlayerColor.Yellow;
            }

            OpponentShotText.Visibility = System.Windows.Visibility.Collapsed;

            gameManager.ChooseStartPlayer(RoundResult);
            systemTray.ChangePlayer(gameManager.ActivePlayer);   

            score.AddRoundResult(Math.Max(RoundResult, 0), -Math.Min(RoundResult, 0));

            CameraAnimation.From = scrollViewer.VerticalOffset;
            CameraAnimation.To = GameManager.Hackline;
            //CameraAnimation.Finish += new AnimationManager.FinishEventHandler(CameraAnimation_Finish);

            CameraAnimation.Start();

            systemTray.IsNewGameEnabled = true;            
        }

        void gameManager_DeliveredStonePostitonChanged(object sender, StonePositionEventArgs e)
        {
            if (gameManager.gameState == GameState.StonePushed || gameManager.gameState == GameState.StoneDelivered || (gameManager.replay != null && gameManager.replay.IsPlaying) || gameManager.IsInternetActive)
            {
                if (e.Y < 3990)
                {
                    scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.dY);//(e.Y);
                }
            }

            if (gameManager.gameState == GameState.StonePushed || gameManager.gameStateReplay == GameState.StonePushed)
            {
                double Y = (e.Y >= 3990.0) ? e.Y - 4185.0 : 3990.0 - 4185.0;

                HandGrid.RenderTransform = new CompositeTransform() { Rotation = gameManager.DeliveryStone.stoneEntity.Rotation, TranslateX = e.X - GameManager.Centerline, TranslateY = Y };                
            }
            //else if (gameManager.gameState == GameState.StoneDelivered || gameManager.gameStateRaplay == GameState.StoneDelivered)
            //{
            //    scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.dY);
            //}
        }

        void gameManager_ActivePlayerChanged(object sender, EventArgs e)
        {
            ActivePlayerChanged();
        }

        private void ActivePlayerChanged()
        {
            MakeScreenshot();

            lock (gameManager)
            {
                if (IsPlayOverInternet)
                {
                    if (gameManager.IsPersonActive)
                    {
                        gameManager.gameData = new GameData();

                        foreach (Stone stone in gameManager.Stones)
                        {
                            gameManager.gameData.AddStoneFrame(stone.stoneEntity);
                        }

                        string GameDataXml = gameManager.gameData.ToXml();

                        CurlingService.UploadDataAsync(App.AuthToken, Opponent.ID, GameDataXml);

                        OpponentShotText.Visibility = System.Windows.Visibility.Visible;
                    }
                    else
                    {
                        OpponentShotText.Visibility = System.Windows.Visibility.Collapsed;
                    }

                    //DownloadAndUploadDataTimer.Start();
                }

                gameManager.StoneToStart();

                if (gameManager.gameState != GameState.GameEnded)
                {
                    if (gameManager.gameState == GameState.StoneOnStart && systemTray.IsAutoScroll && (!IsPlayOverInternet || gameManager.IsInternetActive))
                    {
                        CameraAnimation.Duration = 0.5;
                        CameraAnimation.From = scrollViewer.VerticalOffset;
                        CameraAnimation.To = scrollViewer.ScrollableHeight;

                        Timer = new DispatcherTimer()
                        {
                            Interval = TimeSpan.FromSeconds(1.0 + ((IsPlayOverInternet) ? 2.0 : 0))
                        };

                        Timer.Tick += new EventHandler(Timer_Tick);
                        Timer.Start();
                    }

                    HandGrid.RenderTransform = new RotateTransform() { Angle = 0 };

                    if (gameManager.ActivePlayer == PlayerColor.Yellow)
                    {
                        gameManager.ActivePlayer = PlayerColor.Red;
                    }
                    else
                    {
                        gameManager.ActivePlayer = PlayerColor.Yellow;
                    }

                    systemTray.ChangePlayer(gameManager.ActivePlayer);
                }

                if (BroomManager.IsShowBroom)
                {
                    HideBroom.Begin();
                    BroomManager.IsShowBroom = false;
                }

                systemTray.IsReplayEnabled = (!gameManager.IsComputerActive && !IsPlayOverInternet);

                if (gameManager.IsComputerActive)
                {
                    aiManager.NewRound();
                }

                gameManager.gameData = new GameData();
            }
        }

        void Timer_Tick(object sender, EventArgs e)
        {
            Timer.Stop();

            //if (gameManager.gameState == GameState.StoneOnStart)
            //{
                Dispatcher.BeginInvoke(() =>
                {
                    CameraAnimation.Start();
                });
            //}
        }

        private void PhoneApplicationPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);

            accelerometer = new Accelerometer();
            accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingEventArgs>(accelerometer_ReadingChanged);
            accelerometer.Start();

            CameraAnimation = new AnimationManager();

            if (IsPlayOverInternet)
            {
                using (IsolatedStorageFile Store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (Store.DirectoryExists("GameManager"))
                    {
                        string Path = "\\GameManager\\GameManager.xml";

                        Store.DeleteFile(Path);

                        settings.Remove("GameManager");
                    }
                }
            }

            if (gameManager.gameState != GameState.GameEnded)
            {
                if (settings.Contains("VerticalScroll") && gameManager.gameState == GameState.StoneDelivered)
                {
                    CameraAnimation.Duration = 1.0;

                    CameraAnimation.From = scrollViewer.VerticalOffset;
                    CameraAnimation.To = (double)settings["VerticalScroll"];
                }
                else
                {                    
                    CameraAnimation.Duration = 1.0;
                    CameraAnimation.From = scrollViewer.VerticalOffset;
                    CameraAnimation.To = scrollViewer.ScrollableHeight;

                    if (gameManager.Player1Type == PlayerType.Internet)
                    {
                        CameraAnimation.From = scrollViewer.VerticalOffset;
                        CameraAnimation.To = GameManager.Hackline;
                    }
                }
            }
            else
            {
                CameraAnimation.Duration = 0.5;
                CameraAnimation.From = scrollViewer.VerticalOffset;
                CameraAnimation.To = GameManager.Hackline;
            }

            Timer = new DispatcherTimer()
            {
                Interval = TimeSpan.FromSeconds(1.0)
            };

            Timer.Tick += new EventHandler(Timer_Tick);
            Timer.Start();

            MakeScreenshot();
        }

        void gameManager_StoneAdded(object sender, StoneAddedEventArgs e)
        {
            StonesCanvas.Children.Add(e.stone);
        }
        
        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            double dT = (DateTime.Now.Ticks - LastTickCount) / 10000000.0;

            if (!IsPause)
            {
                gameManager.Update(dT);

                if (gameManager.IsComputerActive)
                    aiManager.Update();

                if (gameManager.replay != null && gameManager.replay.IsPlaying)
                {
                    BroomReplay BroomReplayFrame = gameManager.replay.GetCurrentBroomFrame();

                    if (BroomManager.IsShowBroom && !BroomReplayFrame.Visible)
                    {
                        HideBroom.Begin();
                        BroomManager.IsShowBroom = false;
                        SoundManager.PlayBroomSound(0.0);
                    }
                    else if (!BroomManager.IsShowBroom && BroomReplayFrame.Visible)
                    {
                        ShowBroom.Begin();
                        BroomManager.IsShowBroom = true;
                    }

                    if (BroomManager.IsShowBroom)
                    {
                        BroomImage.RenderTransform = new TranslateTransform() { X = BroomReplayFrame.X - 100, Y = -scrollViewer.VerticalOffset + BroomReplayFrame.Y - 100 };

                        double A = Math.Min(BroomReplayFrame.Intensity / dT * 0.0004, 1.0);
                        SoundManager.PlayBroomSound(A);
                    }
                }
                else
                {
                    gameManager.UseBroom(BroomManager.Intensity, dT);

                    if (BroomManager.IsShowBroom && gameManager.gameState == GameState.StoneDelivered)
                    {
                        gameManager.replay.AddBroomFrame(BroomManager.X, scrollViewer.VerticalOffset + BroomManager.Y, BroomManager.Intensity, true, gameManager.CurrentGameTime);
                    }

                    BroomManager.Reset();
                }

                if (gameManager.gameState == GameState.StoneOnStart && gameManager.IsPersonActive)
                {
                    if (scrollViewer.VerticalOffset >= 3998.0 && !IsShowHand && !SupressHand && (gameManager.replay == null || !gameManager.replay.IsPlaying))
                    {
                        ShowHand.Begin();
                        ShowMap.Begin();
                        IsShowHand = true;
                    }
                }

                if (scrollViewer.VerticalOffset == 0.0 && SupressSystemTray)
                {
                    systemTray.Collapse();
                }
                else
                {
                    if (!systemTray.IsSystemTrayExpanded)
                    {
                        systemTray.Expand();
                    }
                }
            }

            if (!CameraAnimation.IsFinish)
            {
                scrollViewer.ScrollToVerticalOffset(CameraAnimation.Update(dT));
            }

            VerticalScroll = scrollViewer.VerticalOffset;
            
            LastTickCount = DateTime.Now.Ticks;
        }

        void accelerometer_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
        {
            if ((gameManager.gameState == GameState.StoneOnStart || gameManager.gameState == GameState.StonePushed) && gameManager.IsPersonActive && !IsPause)
            {
                double X = Math.Atan2(e.X, e.Z) / Math.PI;
                X = (X < 0) ? (-1 - X) * 2 : X = (1 - X) * 2;

                double Y = -Math.Atan2(e.Y, e.Z) / Math.PI;
                Y = (Y < 0) ? (-1 - Y) * 2 : Y = (1 - Y) * 2;

                double Threshold = 0.9;
                if (X > -Threshold && X < Threshold && Y > -Threshold && Y < Threshold)
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        if (gameManager.gameState == GameState.StoneOnStart)
                        {
                            gameManager.RotateDeliveryStone(X * 30);
                        }

                        if (gameManager.gameState == GameState.StonePushed)
                        {
                            double dT = (e.Timestamp.Ticks - LastAccelerometerReading) / 10000000.0;

                            gameManager.AddRotationImpulse(Math.Max(Math.Min((gameManager.StoneInitialRotation - X * 30) * 50, 200), -200), dT);
                        }

                        if (gameManager.gameState == GameState.StoneOnStart && gameManager.DeliveryStone != null)
                        {
                            HandGrid.RenderTransform = new RotateTransform() { Angle = gameManager.DeliveryStone.stoneEntity.Rotation };
                        }
                    });
                }
            }

            LastAccelerometerReading = e.Timestamp.Ticks;
        }

        private void scrollViewer_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
        {
            if (gameManager.gameState == GameState.StoneOnStart)
            {
                if (scrollViewer.VerticalOffset == 3998.0 && IsShowHand)
                {
                    HideHand.Begin();
                    HideMap.Begin();
                    IsShowHand = false;
                    SupressHand = true;
                }
            }

            if (scrollViewer.VerticalOffset == 0.0)
            {
                if (!SupressSystemTray)
                    SupressSystemTray = true;
            }
        } 

        private void scrollViewer_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
        {
            if (gameManager.gameState == GameState.StoneDelivered)
            {
                if (!BroomManager.IsShowBroom && gameManager.IsPersonActive)
                {
                    if (Math.Abs(e.CumulativeManipulation.Translation.X) > 10.0)
                    {
                        ShowBroom.Begin();
                        BroomManager.IsShowBroom = true;
                    }
                }

                if (BroomManager.IsShowBroom)
                {
                    BroomManager.Update(e.DeltaManipulation.Translation.X);
                    BroomManager.X = e.ManipulationOrigin.X;
                    BroomManager.Y = e.ManipulationOrigin.Y;

                    BroomImage.RenderTransform = new TranslateTransform() { X = e.ManipulationOrigin.X - 100, Y = e.ManipulationOrigin.Y - 100 };
                }
            }
        }

        private void scrollViewer_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
        {
            if (BroomManager.IsShowBroom)
            {
                HideBroom.Begin();
                BroomManager.IsShowBroom = false;
                gameManager.replay.AddBroomFrame(e.ManipulationOrigin.X, e.ManipulationOrigin.Y, 0.0, false, gameManager.CurrentGameTime);
            }

            if (gameManager.gameState == GameState.StoneOnStart && gameManager.IsPersonActive)
            {
                if (scrollViewer.VerticalOffset == 3998.0 && !IsShowHand)
                {
                    ShowHand.Begin();
                    ShowMap.Begin();
                    IsShowHand = true;                    
                }
                SupressHand = false;
            }

            SupressSystemTray = false;
        } 

        void HideHand_Completed(object sender, EventArgs e)
        {
            IsShowHand = false;
        }

        void ShowHand_Completed(object sender, EventArgs e)
        {
            IsShowHand = true;
        }

        private void HandGrid_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
        {
            if (gameManager.gameState == GameState.StoneOnStart && scrollViewer.VerticalOffset == 3998.0 && IsShowHand)
            {
                systemTray.IsReplayEnabled = false;

                gameManager.PushStone();

                HideMap.Begin();

                PushStone.Begin();

                FirstHoglineFall = false;

                e.Handled = true;
            }
            else
            {
                e.Handled = false;
            }
        }

        private void HandGrid_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
        {
            if (gameManager.gameState == GameState.StonePushed && !FirstHoglineFall && IsShowHand)
            {
                gameManager.LeaveStone();

                LeaveStone.Begin();

                IsShowHand = false;

                e.Handled = true;
            }
            else
            {
                e.Handled = false;
            }
        }

        private void SystemTrayManipulator_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
        {
            systemTray.Expand();
        }

        void DownloadAndUploadDataTimer_Tick(object sender, EventArgs e)
        {
            if (CurlingService != null)
            {
                CurlingService.DownloadDataAsync(App.AuthToken);
            }
        }

        void CurlingService_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.Result == null)
                {
                    DownloadAndUploadDataTimer.Tick -= new EventHandler(DownloadAndUploadDataTimer_Tick);
                    DownloadAndUploadDataTimer.Stop();
                    MessageBox.Show("Opponent disconnected or network error occured", "Failure", MessageBoxButton.OK);
                }
                else if (e.Result != "")
                {
                    //if (gameManager.gameData.StoneGameFrames.Count == 0)
                    //{
                    //    gameManager.CurrentGameTime = TimeSpan.FromSeconds(-2.0);
                    //}

                    gameManager.gameData = GameData.FromXml(e.Result);

                    for (int i = 0; i < gameManager.Stones.Count; i++)
                    {
                        StoneReplayFrame stoneGameFrame = gameManager.gameData.GetStoneFrame(gameManager.Stones[i].stoneEntity.ID);

                        if ((stoneGameFrame.State == StoneState.WaitDelivery || stoneGameFrame.State == StoneState.OnStart) && (gameManager.Stones[i].stoneEntity.State == StoneState.OnRink || gameManager.Stones[i].stoneEntity.State == StoneState.InOut))
                        {
                            if (gameManager.CurrentStone > 1)
                            {
                                NewGame(false);
                                return;
                            }
                        }

                        gameManager.Stones[i].stoneEntity.X = stoneGameFrame.X;
                        gameManager.Stones[i].stoneEntity.Y = stoneGameFrame.Y;
                        gameManager.Stones[i].stoneEntity.Rotation = stoneGameFrame.Rotation;
                        gameManager.Stones[i].stoneEntity.State = stoneGameFrame.State;
                        gameManager.Stones[i].stoneEntity.State = stoneGameFrame.State;
                        gameManager.Stones[i].stoneEntity.IsProceed = true;
                        if (gameManager.Stones[i].stoneEntity.State == StoneState.OnRink)
                        {
                            gameManager.Stones[i].stoneEntity.DistanceToButton = Math.Sqrt(Math.Pow(gameManager.Stones[i].stoneEntity.X - GameManager.Centerline, 2) + Math.Pow(gameManager.Stones[i].stoneEntity.Y - (GameManager.RinkLength - GameManager.Teeline), 2));
                        }
                    
                    }

                    ActivePlayerChanged();

                    //DownloadAndUploadDataTimer.Stop();
                }
            }
        }

        void CurlingService_UploadDataCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);

            if (gameManager == null)
                return;

            if (!IsPlayOverInternet)
            {
                IsPause = true;
                VisualStateManager.GoToState(this, "PauseOn", true);

                for (int i = 0; i < GameManager.StonesCount; i++)
                {
                    if (!gameManager.Stones[i].stoneEntity.IsStatic)
                    {
                        gameManager.Stones[i].stoneEntity.soundManager.PlayMoveSound(0.0);
                    }
                }

                settings["IsPause"] = true;

                settings["ScrollMode"] = systemTray.IsAutoScroll;
                settings["Sound"] = systemTray.IsSoundOn;
                settings["VerticalScroll"] = VerticalScroll;

                settings["AIManager"] = aiManager;

                settings["Score"] = systemTray.Score;

                if (gameManager.replay != null && gameManager.replay.IsPlaying)
                {
                    gameManager.replay.StopPlay();
                }

                gameManager.StoneAdded -= new GameManager.StoneAddedEventHandler(gameManager_StoneAdded);
                gameManager.DeliveredStonePostitonChanged -= new GameManager.StonePostitonChangedEventHandler(gameManager_DeliveredStonePostitonChanged);
                gameManager.ActivePlayerChanged -= new GameManager.ActivePlayerChangedEventHandler(gameManager_ActivePlayerChanged);
                gameManager.FallEvent -= new GameManager.FallEventHandler(gameManager_Fall);
                gameManager.GameEnded -= new GameManager.GameEndedEventHandler(gameManager_GameEnded);

                PhoneApplicationService.Current.State["NeedSaveGameManager"] = true;
                settings["GameManager"] = gameManager;
                //PhoneApplicationService.Current.State["GameManager"] = gameManager;
                
                //gameManager.Save();
                //settings["gameManager"] = gameManager;

                foreach (Stone stone in gameManager.Stones)
                {
                    if (!stone.stoneEntity.IsProceed && stone.stoneEntity.State != StoneState.WaitDelivery)
                    {
                        stone.stoneEntity.Save();
                    }
                }

                PhoneApplicationService.Current.State["ToMenu"] = true;

                
            }
            
            if (IsPlayOverInternet)
            {
                //CurlingService.SetStatusOfflineAsync(App.AuthToken);
                //CurlingService.CloseAsync();
                CurlingService = null;
                PhoneApplicationService.Current.State.Remove("GameManager");
                settings.Remove("GameManager");
                PhoneApplicationService.Current.State.Remove("CurlingService");
                PhoneApplicationService.Current.State.Remove("Opponent");
                PhoneApplicationService.Current.State.Remove("Player1Name");
                PhoneApplicationService.Current.State.Remove("Player2Name");
                PhoneApplicationService.Current.State.Remove("Player1Type");
                PhoneApplicationService.Current.State.Remove("Player2Type");
                PhoneApplicationService.Current.State.Remove("NeedSaveGameManager");

                score.SaveGameResult(false);

                if (!PhoneApplicationService.Current.State.ContainsKey("GoToMenu"))
                {
                    PhoneApplicationService.Current.State["GoToMenu"] = true;
                }
                else
                {
                    PhoneApplicationService.Current.State.Remove("GoToMenu");
                }
            }

            if (DownloadAndUploadDataTimer != null)
                DownloadAndUploadDataTimer.Stop();

            //settings.Save();
        }

        private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (gameManager.replay != null && gameManager.replay.IsPlaying)
            {
                e.Cancel = true;

                VisualStateManager.GoToState(this, "ReplayCollapsed", true);
                systemTray.IsReplayEnabled = true;
                gameManager.replay.StopPlay();
            }
            else
            {
                if (!IsPause)
                {
                    for (int i = 0; i < GameManager.StonesCount; i++)
                    {
                        if (!gameManager.Stones[i].stoneEntity.IsStatic)
                        {
                            gameManager.Stones[i].stoneEntity.soundManager.PlayMoveSound(0.0);
                        }
                    }

                    IsPause = true;
                    VisualStateManager.GoToState(this, "PauseOn", true);

                    e.Cancel = true;
                }
                else
                {
                    VisualStateManager.GoToState(this, "PauseClose", true);

                    if (NavigationService.CanGoBack)
                    {
                        if (IsPlayOverInternet)
                        {
                            PhoneApplicationService.Current.State["GoToMenu"] = false;
                        }

                        NavigationService.GoBack();
                    }
                }
            }
        }

        private void MenuButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            //IsPause = false;
            VisualStateManager.GoToState(this, "PauseClose", true);

            NavigationService.GoBack();
        }

        private void ResumeButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            IsPause = false;
            VisualStateManager.GoToState(this, "PauseOff", true);
        }

        private void MakeScreenshot()
        {
            //Capture the screen and set it to the internal picture box
            WriteableBitmap bmp = new WriteableBitmap(480, 1950);
            bmp.Render(RinkGrid, new TranslateTransform() { Y = -GameManager.Backline + RinkGrid.Margin.Top + StoneEntity.Radius });
            bmp.Invalidate();
            MapImage.Source = bmp;
        }
    }
}